/**
 * Copyright (C) 2010, 2011 Neofonie GmbH
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package eu.dicode.analysis.demonstrator;

import eu.dicode.analysis.demonstrator.util.Configuration;
import eu.dicode.analysis.demonstrator.util.FileSystemScanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.*;
import java.util.LinkedList;

/**
 * Reads dumped collocation analysis result and sends those results back in json
 * format.
 */
@Controller
public class CollocationDataController {
  /** Logger for this class. */
  private static final Logger LOG = LoggerFactory.getLogger(CollocationDataController.class);
  /** Where in the file system is our collocation data located. */
  private final String collocationRawData;
  /** For retrieving data files */
  private final FileSystemScanner scanner;

  CollocationDataController(final String collocationData) {
    this.collocationRawData = collocationData;
    this.scanner = new FileSystemScanner();
  }

  public CollocationDataController() throws IOException {
    Configuration config = Configuration.getInstance();
    this.collocationRawData = config.getStringValue(Configuration.DICODE_COLLOCATION_LOCATION,
	Configuration.DICODE_DEFAULT_COLLOCATION_LOCATION);
    this.scanner = new FileSystemScanner();
  }

  // TODO think about caching!
  @RequestMapping(value = "/data/colloc/{queryString}/top.data", method = RequestMethod.GET)
  public void topValue(@PathVariable String queryString, final Model model, final Writer responseWriter)
      throws FileNotFoundException {
    File collocFile = this.scanner.getFile(queryString, this.collocationRawData);
    BufferedReader reader = new BufferedReader(new FileReader(collocFile));
    String line;
    try {
      line = reader.readLine();
      StringBuffer result = new StringBuffer("[");
      int counter = 20;
      while (line != null && counter > 0) {
	if (line.startsWith("Key")) {
	  if (result.length() > 1) {
	    result.append(", ");
	  }
	  // Key: http bit.ly: Value: 49952.000139875745 <- format of each line
	  String[] split = line.split(":");
	  result.append("{\"tag\": \"").append(split[1].trim()).append("\", \"count\": \"").append(split[3].trim())
	      .append("\"}");
	}
	line = reader.readLine();
	counter--;
      }
      result.append("]");
      responseWriter.write(result.toString());
    } catch (IOException e) {
      LOG.error(e.getMessage(), e);
    } finally {
      try {
	reader.close();
      } catch (IOException e) {
	LOG.error(e.getMessage());
      }
    }

  }

  @RequestMapping(value = "/data/colloc/{queryString}/bottom.data", method = RequestMethod.GET)
  public void bottomValues(@PathVariable String queryString, final Model model, final Writer responseWriter)
      throws FileNotFoundException {
    File collocFile = this.scanner.getFile(queryString, this.collocationRawData);

    BufferedReader reader = new BufferedReader(new FileReader(collocFile));
    try {
      String line = reader.readLine();

      LinkedList<String> entries = new LinkedList<String>();
      while (line != null) {
	if (line.startsWith("Key")) {
	  // Key: http bit.ly: Value: 49952.000139875745 <- format of each line
	  String[] split = line.split(":");
	  StringBuffer buffer = new StringBuffer();
	  buffer.append("{\"tag\": \"").append(split[1].trim()).append("\", \"count\": \"").append(split[3].trim())
	      .append("\"}");
	  entries.addLast(buffer.toString());
	  if (entries.size() > 20) {
	    entries.removeFirst();
	  }
	}
	line = reader.readLine();
      }

      StringBuffer result = new StringBuffer("[");
      for (String entry : entries) {
	if (result.length() > 1) {
	  result.append(", ");
	}
	result.append(entry);
      }
      reader.close();
      result.append("]");
      responseWriter.write(result.toString());

    } catch (IOException e) {
      LOG.error(e.getMessage(), e);
    } finally {
      try {
	reader.close();
      } catch (IOException e) {
	LOG.error(e.getMessage());
      }
    }

  }

  @RequestMapping(value = "/data/colloc/{queryString}/chart.data", method = RequestMethod.GET)
  public void chart(@PathVariable String queryString, final Model model, final Writer responseWriter)
      throws IOException, FileNotFoundException {
    File collocFile = this.scanner.getFile(queryString, this.collocationRawData);
    BufferedReader reader = new BufferedReader(new FileReader(collocFile));
    try {
      String line = reader.readLine();
      StringBuffer result = new StringBuffer("[[");
      int counter = 0;
      while (line != null) {
	if (line.startsWith("Key")) {
	  if (counter % 1000 == 0) {
	    if (result.length() > 2) {
	      result.append(",");
	    }
	    // Key: http bit.ly: Value: 49952.000139875745 <- format of each
	    // line
	    // [2, 7792.4952347008675] <- format of the target lines
	    String[] split = line.split(":");
	    String member = split[3].trim();
	    int index = member.indexOf('.');
	    String y = member.substring(0, index);
	    result.append("[").append(counter).append(", ").append(y).append("]");
	  }
	}
	line = reader.readLine();
	counter++;
      }
      reader.close();
      result.append("]]");
      responseWriter.write(result.toString());
    } catch (IOException e) {
      LOG.error(e.getMessage(), e);
    } finally {
      try {
	reader.close();
      } catch (IOException e) {
	LOG.error(e.getMessage());
      }
    }
  }
}
